/*-------------------------------------------------------------------------
 *
 * pg_attribute.h
 *	  "属性"系统目录 (pg_attribute) 的定义
 *
 * pg_attribute 的初始内容在编译时由 genbki.pl 生成，因此没有 pg_attribute.dat 文件。只有 "引导" 的关系需要被包含。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/catalog/pg_attribute.h
 *
 * NOTES
 *	  Catalog.pm 模块读取此文件并推导模式信息。
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_ATTRIBUTE_H
#define PG_ATTRIBUTE_H

#include "catalog/genbki.h"
#include "catalog/pg_attribute_d.h"

/* ----------------
 *		pg_attribute定义。 cpp将其转换为
 *		typedef struct FormData_pg_attribute
 *
 *		如果您更改以下内容，请确保在catalog/heap.c中也更改系统属性的结构。
 *		您可能还需要更改catalog/genbki.pl。
 * ----------------
 */
CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,AttributeRelation_Rowtype_Id) BKI_SCHEMA_MACRO
{
	Oid			attrelid BKI_LOOKUP(pg_class);	/* 包含此属性的关系的OID */
	NameData	attname;		/* 属性名称 */

	/*
	 * atttypid是Catalog Class pg_type中定义此属性数据类型的实例的OID（例如：int4）。
	 * 该实例中的信息与此实例的attlen、attbyval和attalign属性冗余，因此它们最好匹配，否则Postgres将失败。
	 * 在已删除列的条目中，此字段设置为零，因为pg_type条目可能不再存在；
	 * 但我们依赖attlen、attbyval和attalign仍然告诉我们表中值的大小。
	 */
	Oid			atttypid BKI_LOOKUP_OPT(pg_type);

	/*
	 * attstattarget是VACUUM ANALYZE此列时要收集的统计数据点的目标数量。
	 * 此处为零表示我们不希望收集此列的任何统计信息。
	 * 此处的“-1”表示未为此列显式设置值，因此ANALYZE应使用默认设置。
	 */
	int32		attstattarget BKI_DEFAULT(-1);

	/*
	 * attlen是此属性的pg_type中的typlen字段的副本。
	 * 请参见上面的atttypid注释。
	 */
	int16		attlen;

	/*
	 * attnum是属性的“属性编号”：唯一识别此属性在其类别中的值。
	 * 对于用户属性，属性编号大于0且不大于类别中的属性数目。
	 * 例如，如果pg_class类表示Class XYZ有10个属性，则pg_attribute类中的用户属性编号必须是1-10。
	 *
	 * 系统属性具有小于0的属性编号，这些编号在类中是唯一的，但不受限于任何特定范围。
	 *
	 * 请注意，(attnum - 1)通常用作数组的索引。
	 */
	int16		attnum;

	/*
	 * attndims是声明的维数，如果是数组类型，则为零。
	 */
	int32		attndims;

	/*
	 * fastgetattr()使用attcacheoff来缓存堆元组中属性的字节偏移。
	 * 在pg_attribute中实际存储的值（-1）表示没有缓存值。
	 * 但是，当我们将这些元组复制到元组描述符中时，我们可能会更新副本中的attcacheoff。
	 * 这加快了属性遍历过程。
	 */
	int32		attcacheoff BKI_DEFAULT(-1);

	/*
	 * atttypmod记录在表创建时提供的特定于类型的数据（例如，varchar字段的最大长度）。
	 * 它作为第三个参数传递给特定于类型的输入和输出函数。
	 * 对于不需要typmod的类型，该值通常为-1。
	 */
	int32		atttypmod BKI_DEFAULT(-1);

	/*
	 * attbyval是此属性的pg_type中typbyval字段的副本。
	 * 请参见上面的atttypid注释。
	 */
	bool		attbyval;

	/*
	 * attalign是此属性的pg_type中typalign字段的副本。
	 * 请参见上面的atttypid注释。
	 */
	char		attalign;

	/*----------
	 * attstorage告诉VARLENA属性，在给定元组无法适应页面时，堆访问方法可以对其做什么。
	 * 可能的值与pg_type.typstorage相同（请参见TYPSTORAGE宏）。
	 *----------
	 */
	char		attstorage;

	/*
	 * attcompression设置属性的当前压缩方法。
	 * 通常这是InvalidCompressionMethod（'\0'），表示使用当前默认设置（请参见default_toast_compression）。
	 * 否则，'p'选择pglz压缩，而'l'选择LZ4压缩。
	 * 但是，每当attstorage不允许压缩时，此字段将被忽略。
	 */
	char		attcompression BKI_DEFAULT('\0');

	/* 此标志表示“NOT NULL”约束 */
	bool		attnotnull;

	/* 是否具有默认值 */
	bool		atthasdef BKI_DEFAULT(f);

	/* 是否存在缺失值 */
	bool		atthasmissing BKI_DEFAULT(f);

	/* 下面的 ATTRIBUTE_IDENTITY_* 常量之一，或 '\0' */
	char		attidentity BKI_DEFAULT('\0');

	/* 下面的 ATTRIBUTE_GENERATED_* 常量之一，或 '\0' */
	char		attgenerated BKI_DEFAULT('\0');

	/* 是否被删除（即逻辑上不可见） */
	bool		attisdropped BKI_DEFAULT(f);

	/*
	 * 此标志指定此列是否曾经有过本地定义。
	 * 对于正常的非继承列，此标志会被设置，但对于
	 * 如果在 CREATE TABLE INHERITS 中明确列出，从父级继承的
	 * 列也会被设置。当使用 ALTER TABLE NO INHERIT 从
	 * 表中删除继承时，也会设置此标志。如果该标志被设置，即使
	 * 父级的 DROP COLUMN 导致该列的 attinhcount 变为零，
	 * 该列也不会被删除。
	 */
	bool		attislocal BKI_DEFAULT(t);

	/* 从直接父关系继承的次数 */
	int32		attinhcount BKI_DEFAULT(0);

	/* 属性的排序规则（如果有） */
	Oid			attcollation BKI_LOOKUP_OPT(pg_collation);

#ifdef CATALOG_VARLEN			/* 可变长度字段从这里开始 */
	/* 注意：以下字段不在元组描述符中。 */

	/* 列级访问权限 */
	aclitem		attacl[1] BKI_DEFAULT(_null_);

	/* 列级选项 */
	text		attoptions[1] BKI_DEFAULT(_null_);

	/* 列级 FDW 选项 */
	text		attfdwoptions[1] BKI_DEFAULT(_null_);

	/*
	 * 添加列的缺失值。这是一个单元素数组，让我们
	 * 可以在此处存储属性类型的值。
	 */
	anyarray	attmissingval BKI_DEFAULT(_null_);
#endif
} FormData_pg_attribute;

/*
 * ATTRIBUTE_FIXED_PART_SIZE 是 pg_attribute 行的固定布局、
 * 保证非空部分的大小。实际上，这是被复制到元组描述符的行的大小，
 * 因此不要指望能够访问除真正的元组外的可变长度字段！
 */
#define ATTRIBUTE_FIXED_PART_SIZE \
	(offsetof(FormData_pg_attribute,attcollation) + sizeof(Oid))

/* ----------------
 *		Form_pg_attribute 对应一个指向具有
 *		pg_attribute 关系格式的元组的指针。
 * ----------------
 */
typedef FormData_pg_attribute *Form_pg_attribute;

DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index, 2658, AttributeRelidNameIndexId, on pg_attribute using btree(attrelid oid_ops, attname name_ops));
DECLARE_UNIQUE_INDEX_PKEY(pg_attribute_relid_attnum_index, 2659, AttributeRelidNumIndexId, on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));

#ifdef EXPOSE_TO_CLIENT_CODE

#define		  ATTRIBUTE_IDENTITY_ALWAYS		'a'
#define		  ATTRIBUTE_IDENTITY_BY_DEFAULT 'd'

#define		  ATTRIBUTE_GENERATED_STORED	's'

#endif							/* EXPOSE_TO_CLIENT_CODE */

#endif							/* PG_ATTRIBUTE_H */
